package com.li.my_tiny_spring.beans.factory;

import java.lang.reflect.Field;
import java.util.Optional;

import com.li.my_tiny_spring.beans.definition.BeanDefinition;
import com.li.my_tiny_spring.beans.definition.FiledType;
import com.li.my_tiny_spring.beans.definition.PropertyValues;
import com.li.my_tiny_spring.exception.impl.MyIllegalStateException;

public class AutowireCapableBeanFactory extends AbstractBeanFactory {

	@Override
	protected Object doCreateBean(BeanDefinition beanDefinition) {
		Object bean = createBeanInstance(beanDefinition.getBeanClass());
		applyPropertyValues(bean, beanDefinition);
		return bean;
	}
	private Object createBeanInstance(Class<?> beanClass) {
		try {
			return beanClass.newInstance();
		} catch (InstantiationException | IllegalAccessException e) {
			throw new MyIllegalStateException(e);
		}
		
	}

	private void applyPropertyValues(Object bean, BeanDefinition beanDefinition) {
		PropertyValues propertyValues = Optional.of(beanDefinition.getPropertyValues()).orElse(new PropertyValues());
		propertyValues.getPropertyValueList().stream().forEach((propertyValue) -> {
			try {
				Class<?> beanClass = beanDefinition.getBeanClass();
				Field filed = beanClass.getDeclaredField(propertyValue.getFiledName());
				filed.setAccessible(true);
				FiledType filedType = propertyValue.getFiledType();
				if(filedType ==FiledType.STRING) {
					filed.set(bean, propertyValue.getValue());
				}else if(filedType==FiledType.BEAN) {
					String beanName = (String) propertyValue.getValue();
					
					filed.set(bean, getBean(beanName));
				}else {
					throw new MyIllegalStateException().setMessage("has no this type:"+filedType);
				}
			} catch (Exception e) {
				throw new MyIllegalStateException(e);
			}

		});

	}

}
